﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Nh = NHibernate;
using NHibernate.Linq;
using System.Data;
using FoundationLib.Ifc.Data;

namespace FoundationLib.Data.NHibernate
{
	/// <summary>
	/// A proxy for an NHibernate session.
	/// </summary>
	public class NHibernateSessionProxy : ISession
	{
		/// <summary>
		/// The underlying NHibernate session
		/// </summary>
		private Nh.ISession session;

		/// <summary>
		/// Creates a new NHibernate session proxy.
		/// </summary>
		/// <param name="session">The underlying NHibernate session</param>
		public NHibernateSessionProxy(Nh.ISession session)
		{
			Contract.Requires(session != null);
			this.session = session;
		}

		/// <see cref="ISession.Close()"/>
		public void Close()
		{
			session.Close();
		}

		/// <see cref="ISession.SubmitChanges()"/>
		public void SubmitChanges()
		{
			session.Flush();
		}

		/// <see cref="ITransactionProvider.Transaction"/>
		public ITransaction Transaction
		{
			get { return new NHibernateTransactionProxy(this.session.Transaction); }
		}

		/// <see cref="ITransactionProvider.BeginTransaction()"/>
		public ITransaction BeginTransaction()
		{
			return new NHibernateTransactionProxy(this.session.BeginTransaction());
		}

		/// <see cref="ITransactionProvider.BeginTransaction(IsolationLevel)"/>
		public ITransaction BeginTransaction(IsolationLevel isolationLevel)
		{
			return new NHibernateTransactionProxy(this.session.BeginTransaction(isolationLevel));
		}
		
		/// <summary>
		/// Disposes of the instance and releases managed resources.
		/// </summary>
		/// <param name="disposing">True if managed resources are to be released</param>
		protected virtual void Dispose(bool disposing)
		{
			if (disposing)
			{
				this.session.Dispose();
				this.session = null;
			}
		}

		/// <see cref="IDisposable.Dispose()"/>
		public void Dispose()
		{
			this.Dispose(true);
			GC.SuppressFinalize(this);
		}
	}
}
